/**
 * package: core
 * author: zhaiyujin
 * description:
 */
package core

import (
	"fmt"
	"github.com/spf13/viper"
	"gorm.io/driver/mysql"
	"gorm.io/driver/sqlite"
	_ "gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"huanteng/vendors/gcasbin"
	"huanteng/web/database/migrations"
	"huanteng/web/database/seeds"
	"huanteng/web/global/application"
	"time"
)

func InitDB()  {
	var db *gorm.DB
	db=NewDatasource(config)
	//数据migrate
	migrations.Migrations(db)
	//casbin定义
	Enforcer:=gcasbin.NewCasbin(db)
	//赋值
	application.Enforcer=Enforcer
	application.DB=db
	//数据填充
	seeds.Seeds(db,Enforcer)

}

func NewDatasource(config *viper.Viper)*gorm.DB  {

	var DB *gorm.DB
	logMode:=config.GetString("datasource.logger.LogMode")
	loggerModel :=map[string]logger.LogLevel{
		"Silent": 1,
		"Error":2,
		"Warn":3,
		"Info":4,
	}
	sqlconfig:=&gorm.Config{
		Logger: logger.Default.LogMode(loggerModel[logMode]),
		//NamingStrategy: schema.NamingStrategy{SingularTable: true},//表名不加S
	}

	switch config.GetString("datasource.default") {
	case "mysql":
		DB=InitMysql(config,sqlconfig)
	default:
		DB=InitSqlite3(config,sqlconfig)

	}


	sqlDB, _:= DB.DB()
	//sqlDB.SingularTable(true)//表生成结尾不带s
	sqlDB.SetConnMaxLifetime(1 * time.Second)
	// SetConnMaxLifetime设置连接可以重用的最长时间。
	sqlDB.SetMaxIdleConns(20)   //最大打开的连接数
	sqlDB.SetMaxOpenConns(2000) //设置最大闲置个数

	// 启用Logger，显示详细日志
	//DB.LogMode(true)
	//关闭数据库并阻止启动新查询。关闭，然后等待所有已开始在服务器上处理的查询完成。关闭数据库很少，因为数据库句柄是长期存在的并且在许多goroutine之间共享。
	//延迟关闭
	//defer sqlDB.Close()
	fmt.Println("初始化数据库成功......")
	return DB

}

func InitMysql(config *viper.Viper,sqlconfig *gorm.Config)*gorm.DB {

	//global.global.Config.Unmarshal(&config) //将配置文件绑定到config上
	host:=config.GetString("datasource.mysql.host")
	ports:=config.GetString("datasource.mysql.ports")
	dbName:=config.GetString("datasource.mysql.dbName")
	userName:=config.GetString("datasource.mysql.userName")
	passWord:=config.GetString("datasource.mysql.passWord")
	charset:=config.GetString("datasource.mysql.charset")

	//fmt.Println(host)
	//Local:Asia/Shanghai
	dsn:=userName+":"+passWord+"@("+host+":"+ports+")/"+dbName+"?charset="+charset+"&parseTime=True&loc=Local"

	DB, err := gorm.Open(mysql.Open(dsn), sqlconfig)
	if err !=nil{
		panic(err)
	}
	return DB
}
func InitSqlite3(config *viper.Viper,sqlconfig *gorm.Config)*gorm.DB  {
	path:=config.GetString("datasource.sqlite3.path")
	db, err := gorm.Open(sqlite.Open(path),sqlconfig)
	if err !=nil{
		panic(err)
	}
	return db
}
